#!/usr/bin/env python
#-*-encoding:utf-8-*-
'''
Created on 2014年12月4日

@author: chenyongbing
'''
import sys,os
current_dir = os.path.dirname(__file__)

sys.path.append(os.path.join(current_dir,'../../'))

from base.PyEmail import *
from base.retail_datas import myRetailDatas

from localConfig import LocalConfig
myLocalConfig = LocalConfig()
import sys

import openpyxl

import datetime,re

from base.mofi_datas import myMofiDatas

import logging


class ApOffLineMonitor(object):
    '''
        ap离线报警
    '''


    def __init__(self,logging=None):
        '''
            Constructor
            msg level : 0 正常
                        1 warn
                        2 err
        '''
        pass
        
    
    def format_time_to_datetime(self,timeStr=''):
        if not re.search('^[\d]{4}-[\d]{2}-[\d]{2} [\d]{2}:[\d]{2}:[\d]{2}$',timeStr):
            pass
            return
        time_year = int(timeStr[:4])
        time_month = int(timeStr[5:7])
        time_day = int(timeStr[8:10])
        time_hour = int(timeStr[11:13])
        time_min = int(timeStr[14:16])
        time_sec = int(timeStr[17:19])
        return datetime.datetime(time_year,time_month,time_day,time_hour,time_min,time_sec)
        

    def monitor_aps_and_sendmsgs(self,devices=[],start='10:00:00',end="21:00:00",warn_min=60,err_min=120,interval=30,type='every'):
        now = datetime.datetime.today()
        now_sec = now.strftime('%s')
        
        start_datetime = self.format_time_to_datetime(now.strftime('%Y-%m-%d')+' '+start)
        #print start_datetime
        start_sec = start_datetime.strftime('%s')
        #print '--',start_sec
        msgs = []
        now_h = now.strftime('%H:%M:%S')
        #print now_h,start,end
        if now_h<start or now_h>end:
            logging.warning("now:%s not in %s-%s"%(now_h,start,end))
            return msgs
        else:
            logging.info('now :%s in %s-%s'%(now_h,start,end))
        
        #print len(devices)
        for device in devices:
            device = device.encode("utf-8")
            device_version  = myMofiDatas.get_device_version(device=device)
            offline_time = myMofiDatas.get_ap_last_offline_time(device=device,version=device_version)
            if offline_time==None:
                msgs.append({'device':device,'type':'online','level':0})
                continue
            offline_hour = offline_time.strftime('%H:%M:%S')
            
            #print int((now-offline_time).total_seconds())>=err_min * 60
            #print  (int(now_sec) < int(start_sec)+interval*60)
            try:
                #offline_seconds = int((now-offline_time).total_seconds())
                offline_seconds = int(now.strftime('%s')) - int(offline_time.strftime('%s'))
            except:
                offline_seconds = -1
          
#             if offline_seconds >=err_min * 60 and (int(now_sec) < int(start_sec)+interval*60) and type=='every':
#                 #print "yes"
#                 msgs.append({'device':device,'offline_time':offline_time.strftime('%Y-%m-%d %X'),'type':'offline','level':2})
            
            if offline_seconds <=0:
                msgs.append({'device':device,'type':'online','level':0})
                logging.info('设备 %s 正常在线.'%device)
                continue
            
            if offline_seconds<err_min * 60:
                level = 1
            elif (interval+err_min)*60>offline_seconds>=err_min*60:
                level = 3
            elif offline_seconds >= (interval+err_min)*60:
                level = 2
            else:
                level = 0
            logging.info("设备 %s 已于 %s 离线,离线时间%s,err level %s."%(device,offline_time.strftime('%y-%m-%d %X'),offline_seconds/60.0,level))
            msgs.append({'device':device,'offline_time':offline_time.strftime('%Y-%m-%d %X'),'type':'offline','level':level})  
#             
#             
#             if (interval+err_min)*60>offline_seconds>=err_min * 60 and type=='every':
#                 msgs.append({'device':device,'offline_time':offline_time.strftime('%Y-%m-%d %X'),'type':'offline','level':2})
#                 #msgs.append("设备 %s 已于 %s 离线,离线时间已超过%s小时,请处理."%(device,offline_time.strftime('%y-%m-%d %X'),err_min))
#             
#             elif (interval+warn_min)*60>offline_seconds>=warn_min * 60 and type=='every':
#                 msgs.append({'device':device,'offline_time':offline_time.strftime('%Y-%m-%d %X'),'type':'offline','level':1})
#                 #msgs.append("设备 %s 已于 %s 离线,离线时间已超过%s小时,请处理."%(device,offline_time.strftime('%y-%m-%d %X'),warn_min))
#             elif offline_seconds > 0 and type=='once':
#                 msgs.append({'device':device,'offline_time':offline_time.strftime('%Y-%m-%d %X'),'type':'offline','level':2})
#             elif type=='once':
#                 msgs.append({'device':device,'type':'online','level':0})
#             else:
#                 msgs.append({'device':device,'offline_time':offline_time.strftime('%Y-%m-%d %X'),'type':'offline','level':0})
#                 #print (now-offline_time).total_seconds()
#                 logging.info("设备 %s 已于 %s 离线,离线时间大于%s."%(device,offline_time.strftime('%y-%m-%d %X'),err_min))
#                 continue
        return msgs
    
    def to_excel(self,msgs=[],toList=[],sub=u"设备状态",template_file='',export_file=''):
        
        print "msgs length ",len(msgs)
        gmsgs = {}
        mail_user = myLocalConfig.email_user
        mail_pass = myLocalConfig.email_passwd
        mail_host = myLocalConfig.email_smtp
        mail_postfix = myLocalConfig.email_postfix
        if len(toList)==0:
            logging.error('收件人列表为空.')
            return
        if len(msgs)==0:
            logging.error('无设备需要报警.')
            return
        contents = ''
        for msg in msgs:
            device = msg['device']
            type = msg['type']
            
            
            group = myRetailDatas.get_group_name(device=device)
            
            if type == 'online':
                type_name = u'在线'
            elif type == 'offline':
                type_name = u'离线'
            logging.debug("device:%s %s"%(device,type_name))
            if group not in gmsgs.keys():
                gmsgs[group] = {}
            gmsgs[group][device]=type_name
        wb = openpyxl.load_workbook(template_file)
        ws = wb.get_sheet_by_name(wb.get_sheet_names()[0])
        i = 1
        for group , devMsgs in gmsgs.iteritems():
            
            for device , type_name in devMsgs.iteritems():
                i+=1
                print group , device,type_name
                ws.cell(row=i,column=1).value = group
                ws.cell(row=i,column=2).value = device
                ws.cell(row=i,column=3).value = type_name
        wb.save(export_file)
    
    
    def to_html(self,msgs=[],send_level=2):
        html_start = u'''<div class="container-fluid">
                    <div class="row-fluid">
                        <div class="span12">
                        <h3>
                            设备异常记录
                        </h3>
                            <table class="table">
                                <thead>
                                    <tr>
                                        <th>
                                            公司
                                        </th>
                                        <th>
                                            门店
                                        </th>
                                        <th>
                                            设备
                                        </th>
                                        <th>
                                            离线时间
                                        </th>
                                    </tr>
                                </thead>
                                <tbody>'''
        html_end='''

                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>'''
        html = html_start
        mtype = False
        for msg in msgs:
            device = msg['device']
            type = msg['type']
            if type!='offline':continue
            if not msg.has_key('level'):continue
            level = msg['level']
            if level < send_level:continue
            offline_time = msg['offline_time']
            mtype = True
            
            group_name = myRetailDatas.get_group_name(device=device)
            company_name = myRetailDatas.get_comp_name(device=device)
            html=html+'\n'+u'''<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>'''%(company_name,group_name,device,offline_time)
        html = html+html_end
        if mtype == False:return None
        return html
    def sendmail(self,msgs=[],toList=[],sub='设备异常提醒',send_level=2):
        mail_user = myLocalConfig.email_user
        mail_pass = myLocalConfig.email_passwd
        mail_host = myLocalConfig.email_smtp
        mail_postfix = myLocalConfig.email_postfix
        if len(toList)==0:
            logging.error('收件人列表为空.')
            return
        if len(msgs)==0:
            logging.warn('无设备需要报警.')
            return
#         contents = ''
#         for msg in msgs:
#             device = msg['device']
#             type = msg['type']
#             if type!='offline':continue
#             offline_time = msg['offline_time']
#             
#             group = myAnalyzeConfig.getGroupName(device=device)
#             content = u'设备:%s 门店:%s 离线时间:%s'%(device,group,offline_time)
#             contents=contents+content+'\n'
#         #contents = '\n'.join(msgs)
        contents = self.to_html(msgs,send_level=send_level)
        if contents==None:
            logging.warn('无设备需要报警.')
            return
        logging.info(u'向 %s 发送邮件,内容为 %s'%(','.join(toList),contents))
        ret = send_mail(mail_user, mail_pass, mail_host, mail_postfix, toList, sub, contents,stype='html')
        try:
            retStatus = ret['status']
            retMsgs = ret['msgs']
            if retStatus==True:
                logging.info(retMsgs)
            else:
                logging.error(retMsgs)
        except Exception,error:
            logging.error(str(error))
if __name__ == '__main__':
    import argparse,re
    parser = argparse.ArgumentParser(description='args')
    #parser.add_argument('--devices',metavar=u"devices",default='048d38584e70,048d38565008')
    parser.add_argument('--devices',metavar=u"devices",default=None)
    parser.add_argument('--groups',metavar=u" groups",default=None)

    parser.add_argument('--tolist',metavar=u"tolist",default='chen.yongbing@zhimatech.com')
    parser.add_argument('--warn_min',metavar=u"WARNING",default=10,type=float)
    parser.add_argument('--err_min',metavar=u"CRITICAL",default=10,type=float)
    parser.add_argument('--run_cycle',metavar=u"RUNNING CYCLE",default=10,type=float)
    parser.add_argument('--start',metavar=u"Monitor Start",default="09:00:00")
    parser.add_argument('--end',metavar=u"Monitor End",default="21:00:00")
    parser.add_argument('--send_level',metavar=u"正常：0，warn：1，err：2",default=2,type=int)
    parser.add_argument('--first_level',metavar=u"正常：0，warn：1，err：2",default=1,type=int)
    parser.add_argument('--rule',metavar=u'',default=None)
    parser.add_argument('--black_list',metavar=u"shop group list",default=None)
    args = parser.parse_args()
    tolist = args.tolist
    devices = args.devices
#     comp_groups = args.comp_groups
#     prov_groups = args.prov_groups
#     city_groups = args.city_groups
#     dist_groups = args.dist_groups
    groups = args.groups
    warn_min = args.warn_min
    err_min = args.err_min
    interval = args.run_cycle
    start = args.start
    end = args.end
    send_level = args.send_level
    first_level = args.first_level
    rule = args.rule
    black_list = args.black_list
    if black_list!=None:
        black_list = black_list.split(',')
    if rule!=None and myLocalConfig.rules.has_key(rule):
        sub_name = myLocalConfig.rules[rule]['name']
        groups = myLocalConfig.rules[rule]['groups']
        err_min = int(myLocalConfig.rules[rule]['err_min'])
        interval = int(myLocalConfig.rules[rule]['run_cycle'])
        start = myLocalConfig.rules[rule]['start']
        end = myLocalConfig.rules[rule]['end']
        send_level = int(myLocalConfig.rules[rule]['send_level'])
        first_level = int(myLocalConfig.rules[rule]['first_level'])
        tolist = ','.join(myLocalConfig.rules[rule]['mail_to_list'])
        black_list = myLocalConfig.rules[rule]['black_list']
        
        
    now_min = datetime.datetime.today().strftime('%H:%M')
    today = datetime.date.today().strftime('%Y-%m-%d')
    first_run_time = datetime.datetime(int(today[:4]),int(today[5:7]),int(today[8:10]),int(start[:2]),int(start[3:5]),int(start[6:8]))
    second_run_time = (first_run_time + datetime.timedelta(interval/(60.0*24))).strftime('%H:%M:%S')
    if  second_run_time[:5]>now_min >= start[:5]:
        send_level = first_level
    if devices!=None:
        deviceList = devices.split(',')
    elif groups!=None:
        logging.error('groups %s'%len(groups.split(',')))
        logging.error(str(groups.split(',')))
        #deviceList = myAnalyzeConfig.getDevices(groups=groups.split(','))
        newGroups = myRetailDatas.get_shop_groups_by_group(groups.split(','))
        deviceList = myRetailDatas.get_devices_by_groups(newGroups)
    else:
        logging.error( "you must input groups or devices.")
        sys.exit()
    logging.error(len(deviceList))
    
    if black_list:
        black_group_list = myRetailDatas.get_shop_groups_by_group(black_list)
        black_device_list = myRetailDatas.get_devices_by_groups(black_group_list)
        logging.error(black_group_list)
        logging.error(black_device_list)
        deviceList = list(set(deviceList) - set(black_device_list))
    logging.error( len(deviceList))
    #sys.exit()
        
    myApOffLineMonitor = ApOffLineMonitor()
    #msgs = []
    #msgs = myApOffLineMonitor.monitor_aps_and_sendmsgs(devices=deviceList,start=start,end=end, warn_min=warn_min, err_min=err_min, interval=interval,type=type)

    msgs = myApOffLineMonitor.monitor_aps_and_sendmsgs(devices=deviceList,start=start,end=end, warn_min=warn_min, err_min=err_min, interval=interval,type=type)
    myApOffLineMonitor.sendmail(msgs, toList=tolist.split(','),send_level=send_level)

                